From cb3d870a1a0e686e6f8b972cd7aba1b48d31a02f Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 31 Oct 2005 17:10:57 +0100 Subject: [PATCH] From Murillo Fernandes Bernardes : The problem is: There is no mechanism to detect block device setup failure Network devices have the same problem, and are fixed with this too. I handling this problem in the way suggested by aliguori: - hotplug scripts write a "hotplug-status" node on store - Xend DevController.createDevice() check verify this node and return success or throw an exception on failure. - If no changes in "hotplug-status" node after DEVICE_CREATE_TIMEOUT seconds Xend throw an exception showing the problem with hotplug scripts. Signed-off-by: Ewan Mellor --- tools/examples/block-common.sh | 9 +++- tools/examples/vif-bridge | 1 + tools/examples/vif-nat | 2 + tools/examples/vif-route | 2 + tools/examples/xen-hotplug-common.sh | 6 +++ tools/python/xen/xend/server/DevController.py | 41 +++++++++++++++++++ 6 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tools/examples/block-common.sh b/tools/examples/block-common.sh index 1d20550a9d..397f588c71 100644 --- a/tools/examples/block-common.sh +++ b/tools/examples/block-common.sh @@ -42,10 +42,17 @@ write_dev() { local major local minor local pdev - + major=$(stat -L -c %t "$1") minor=$(stat -L -c %T "$1") + + if [ -z $major -o -z $minor ]; then + fatal "Backend device does not exist" + fi + pdev=$(printf "0x%02x%02x" "0x$major" "0x$minor") xenstore_write "$XENBUS_PATH"/physical-device "$pdev" \ "$XENBUS_PATH"/node "$1" + + success } diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 4ba683c25c..d95d8ecef5 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -58,6 +58,7 @@ case "$command" in fatal "brctl addif $bridge $vif failed" ifconfig "$vif" up || fatal "ifconfig $vif up failed" + success ;; down) # vifs are auto-removed from bridge. diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index bf9f40a7b9..2d751edc60 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -54,3 +54,5 @@ esac ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip} handle_iptable() + +success diff --git a/tools/examples/vif-route b/tools/examples/vif-route index beb8e43ef2..c804a01840 100755 --- a/tools/examples/vif-route +++ b/tools/examples/vif-route @@ -46,3 +46,5 @@ if [ "${ip}" ] ; then fi handle_iptable() + +success diff --git a/tools/examples/xen-hotplug-common.sh b/tools/examples/xen-hotplug-common.sh index cc5af864a2..9cce5175a2 100644 --- a/tools/examples/xen-hotplug-common.sh +++ b/tools/examples/xen-hotplug-common.sh @@ -30,10 +30,16 @@ log() { } fatal() { + xenstore_write "$XENBUS_PATH"/hotplug-status error log err "$@" exit 1 } +success() { + # Tell DevController that backend is "connected" + xenstore_write "$XENBUS_PATH"/hotplug-status connected +} + ## # xenstore_read + # diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py index fdc0404235..83363f9281 100644 --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -16,12 +16,18 @@ # Copyright (C) 2005 XenSource Ltd #============================================================================ +from threading import Event from xen.xend import sxp from xen.xend.XendError import VmError from xen.xend.XendLogging import log + from xen.xend.xenstore.xstransact import xstransact +from xen.xend.xenstore.xswatch import xswatch +DEVICE_CREATE_TIMEOUT = 120 +HOTPLUG_STATUS_NODE = "hotplug-status" +HOTPLUG_STATUS_ERROR = "error" class DevController: """Abstract base class for a device controller. Device controllers create @@ -54,6 +60,18 @@ class DevController: self.writeDetails(config, devid, back, front) + status, fn_ret = self.waitForBackend(devid) + if status: + self.destroyDevice(devid) + raise VmError( ("Device %s (%s) could not be connected. " + "Hotplug scripts not working") + % (devid, self.deviceClass)) + + elif fn_ret == HOTPLUG_STATUS_ERROR: + self.destroyDevice(devid) + raise VmError( ("Device %s (%s) could not be connected. " + "Backend device not found!") + % (devid, self.deviceClass)) return devid @@ -242,6 +260,29 @@ class DevController: xstransact.Write(frontpath, frontDetails) xstransact.Write(backpath, backDetails) + def waitForBackend(self,devid): + ev = Event() + + def hotplugStatus(): + status = self.readBackend(devid, HOTPLUG_STATUS_NODE) + if status is not None: + watch.xs.unwatch(backpath, watch) + hotplugStatus.value = status + ev.set() + + hotplugStatus.value = None + frontpath = self.frontendPath(devid) + backpath = xstransact.Read(frontpath, "backend") + + watch = xswatch(backpath, hotplugStatus) + + ev.wait(DEVICE_CREATE_TIMEOUT) + if ev.isSet(): + return (0, hotplugStatus.value) + else: + return (-1, hotplugStatus.value) + + def backendPath(self, backdom, devid): """@param backdom [XendDomainInfo] The backend domain info.""" -- 2.30.2